/**
 * Used to instantiate Boards that are used in chess 
 * games (ordinary chess game, Knight's Tour, Eight Queens)
 * 
 * @author jmikhail
 * @version 1.14
 */




//bugs : pawn check warning skip a turn

package mainClasses;
import pieces.*;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;


public class Board {

	/**
	 * Size of the board
	 */
	public static final int SIZE = 8;
	
	/**
	 * Set to true when a pawn reaches the opponents end of the board and gets promoted
	 */
	public boolean pawnPromoted = false;
	
	/**
	 * Set to true if a check occured on the board
	 */
	public boolean checkmate = false;		
	
	/**
	 * Used to hold a reference to the white king
	 */
	public Piece wking;						
	
	
	/**
	 * Used to hold a reference to the black king
	 */
	public Piece bking;					
	
	/**
	 * Set to true if any of the two kings is in danger
	 */
	public boolean kingInDanger = false;
	
	public boolean changePlayer = true;
	
	/**
	 * 2D array of pieces used to hold references to the pieces
	 */
	Piece[][] items;
	
	public String outputString = " ";
	
	public String currentPlayerName = " ";
	public String oldPlayerName = " ";
	
	

	

	/**
	 * Constructor for the board class. It creates a new 2D array of pieces filled with Null Pieces
	 */
	public Board() {
		this.items = new Piece[SIZE][SIZE];		//Creates a new 2D array of pieces
		for (int i = 0; i < SIZE; i++) {
			for (int j = 0; j < SIZE; j++) {
				this.items[i][j] = new NullPiece(i, j, this);		//Fills it with instances of NullPiece
			}
		}
	}

	
	
	/**
	 * Creates new pieces and places them on the board in the appropriate positions for the
	 * regular chess game
	 */
	public void setUp()
	{
		this.items[1][0] = new Pawn(1, 0, this, "White");
		this.items[1][1] = new Pawn(1, 1, this, "White");
		this.items[1][2] = new Pawn(1, 2, this, "White");
		this.items[1][3] = new Pawn(1, 3, this, "White");
		this.items[1][4] = new Pawn(1, 4, this, "White");
		this.items[1][5] = new Pawn(1, 5, this, "White");
		this.items[1][6] = new Pawn(1, 6, this, "White");
		this.items[1][7] = new Pawn(1, 7, this, "White");
		this.items[0][0] = new Rook(0, 0, this, "White");
		this.items[0][1] = new Knight(0, 1, this, "White");
		this.items[0][2] = new Bishop(0, 2, this, "White");
		this.items[0][3] = new Queen(0, 3, this, "White");
		this.items[0][4] = new King(0, 4, this, "White");
		this.items[0][5] = new Bishop(0, 5, this, "White");
		this.items[0][6] = new Knight(0, 6, this, "White");
		this.items[0][7] = new Rook(0, 7, this, "White");
		for (int i = 2; i < 6; i++) {
			for (int j = 0; j < SIZE; j++) {
				this.items[i][j] = new NullPiece(i, j, this);
			}
		}
		this.items[7][0] = new Rook(7, 0, this, "Black");
		this.items[7][1] = new Knight(7, 1, this, "Black");
		this.items[7][2] = new Bishop(7, 2, this, "Black");
		this.items[7][3] = new Queen(7, 3, this, "Black");
		this.items[7][4] = new King(7, 4, this, "Black");
		this.items[7][5] = new Bishop(7, 5, this, "Black");
		this.items[7][6] = new Knight(7, 6, this, "Black");
		this.items[7][7] = new Rook(7, 7, this, "Black");
		this.items[6][0] = new Pawn(6, 0, this, "Black");
		this.items[6][1] = new Pawn(6, 1, this, "Black");
		this.items[6][2] = new Pawn(6, 2, this, "Black");
		this.items[6][3] = new Pawn(6, 3, this, "Black");
		this.items[6][4] = new Pawn(6, 4, this, "Black");
		this.items[6][5] = new Pawn(6, 5, this, "Black");
		this.items[6][6] = new Pawn(6, 6, this, "Black");
		this.items[6][7] = new Pawn(6, 7, this, "Black");
	}

	public String getOutputString()
	{
		return this.outputString;
	}
	
	public void clearOutputString()
	{
		this.outputString = " ";
	}
	
	public void setChangePlayer(boolean b){
		this.changePlayer = b;
	}
	
	public boolean getChangePlayer(){
		return this.changePlayer;
	}
	
	public void setPlayerName(String s, String y)
	{
		this.oldPlayerName = y;
		this.currentPlayerName = s;
	}
	/**
     * Removes the piece from the board at the location provided. 
     * It removes the item from the 2d array using the point provided as an index 
     * and replacing it by an instance of NullPiece
     * 
     * @param p Position of the piece to be removed
     */
	public void remove(int x, int y) {
		Piece empty = new NullPiece(x, y, this);
		this.items[x][y] = empty;		//Fills the position given with an instance of NullPiece 
	}

	
	
	
	/**
     * Returns the piece corresponding to the location provided. It gets the item from the 2d array using the point provided as an index
     * 
     * @param p Position of the piece needed
     * @return The piece located at the given position
     */
	public Piece getPiece(int x, int y)
	{
		Piece pce = this.items[x][y];
		return pce;
	}

	

	/**
	 * Checks if the given piece has any possible moves on board. It is used during stalemate and checkmate
	 * situations when al the pieces has to be blocked with no possible moves
	 * 
	 * @param p The piece to be checked
	 * @return A boolean set to true if the given piece has atleast one possible move
	 */
	public boolean moveAnywhereOnBoard(Piece p)
	{
		boolean temp_kingInDanget = this.kingInDanger;
		this.kingInDanger = false;
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				if(p.movePossible(i, j))
				{
					if(p.getType().equals("   King  ")||p.getType().equals("BK-->King"))
					{
						if(this.isInDanger(i, j, p.getSide()))
						{
							continue;
						}
					}
					if(p.getType().equals("   King  ")||p.getType().equals("BK-->King"))
					{
						boolean kingCanbeDangered = false;
						Piece temp = p;
						Piece temp_two = this.getPiece(i, j);
						this.remove(p.getX(), p.getY());
						this.remove(i, j);
						if(this.isInDanger(i, j, p.getSide()))
						{
							this.add(temp);
							this.add(temp_two);
							continue;
						}
						for(int o=0; o<8; o++)
						{
							for(int m=0; m<SIZE; m++)
							{
								if(!this.items[o][m].getSide().equals(p.getSide()))
								{
									if((this.items[o][m] instanceof Pawn) && Math.abs(o-i)==1 && Math.abs(m-j)==1)
									{
										if(this.items[o][m].getSide().equals("White") && (o-i)<0)
										{
											this.add(temp);
											this.add(temp_two);
											continue;
										}else if(this.items[o][m].getSide().equals("Black") && (o-i)>0)
										{
											this.add(temp);
											this.add(temp_two);
											continue;
										}
									}
									if(this.items[o][m].movePossible(i, j))
									{
										kingCanbeDangered = true;
									}
								}
							}
						}
						if(kingCanbeDangered)
						{
							this.add(temp);
							this.add(temp_two);
							kingCanbeDangered = false;
							continue;
						}
						this.add(temp);
						this.add(temp_two);
					}
					this.kingInDanger = temp_kingInDanget;
					return true;
				}
			}
		}
		this.kingInDanger = temp_kingInDanget;
		return false;
	}
	

	/**
     * Replaces the piece in the original position (point1) by a null piece and the new position
     * (point2) by a contents of point1
     * 
     * @param p1 Origin of the move
     * @param p2 Destination of the move
     */
	public void swap(int x1, int y1, int x2, int y2) {
		this.getKing();
		Piece piece1 = this.getPiece(x1, y1);
		if(piece1.getType().equals("   King  ")|| piece1.getType().equals("BK-->King"))
		{
			if(this.isInDanger(x2, y2, piece1.getSide()))
			{
				this.outputString = this.currentPlayerName + ": Your king can't move there since that block is in danger";
				this.kingInDanger=true;
				this.changePlayer=false;
				return;
			}
		}
		if(this.items[x1][y1].movePossible(x2, y2)==true)
		{
			if(piece1.getType().equals("  Pawn   ") && piece1.getX()==4)
			{
				Pawn wpawn = (Pawn)piece1;
				try
				{
					Pawn opawn = (Pawn)(wpawn.enPosanPawn);
					if(wpawn.moveEnposan)
					{
						if(opawn.getX()!=10)
						{
							this.remove(opawn.getX(), opawn.getY());
						}
					}
				}catch (ClassCastException e1) {
					
				}
			}else if(piece1.getType().equals("BK-->Pawn")&& piece1.getX()==3)
			{
				Pawn bpawn = (Pawn)piece1;
				try
				{
					Pawn opawn = (Pawn)(bpawn.enPosanPawn);
					if(bpawn.moveEnposan)
					{
						if(opawn.getX()!=10)
						{
							this.remove(opawn.getX(), opawn.getY());
						}
					}
				}catch (ClassCastException e1) {
					
				}
			}
			if(this.items[x1][y1] instanceof King)
			{
				King king = (King)this.items[x1][y1];
				if(king.isCastlingPossible() && !((int) king.getLocation().getX()==10) && !((int) king.getLocation().getY()==10))
				{
					int casX = (int) king.getLocation().getX();
					int casY = (int) king.getLocation().getY();
					if(x2 == casX && y2 == casY)
					{
						Piece rook = king.getRookCastling();
						Point rookDestination = king.getRookDestination();
						this.items[rook.getX()][rook.getY()] = new NullPiece(rook.getX(),rook.getX(), this);
						this.items[(int) rookDestination.getX()][(int) rookDestination.getY()] = rook;
						rook.changePosition((int) rookDestination.getX(), (int) rookDestination.getY());
						
						this.items[king.getX()][king.getY()] = new NullPiece(king.getX(),king.getX(), this);
						this.items[casX][casY] = king;
						king.changePosition(casX, casY);
						return;
	
					}
				}
				if(king.castlingPossible2 && !((int) king.getLocation2().getX()==10) && !((int) king.getLocation2().getY()==10))
				{
					int casX = (int) king.getLocation2().getX();
					int casY = (int) king.getLocation2().getY();
					if(x2 == casX && y2 == casY)
					{
						Piece rook = king.getRookCastling2();
						Point rookDestination = king.getRookDestination2();
						this.items[rook.getX()][rook.getY()] = new NullPiece(rook.getX(),rook.getX(), this);
						this.items[(int) rookDestination.getX()][(int) rookDestination.getY()] = rook;
						rook.changePosition((int) rookDestination.getX(), (int) rookDestination.getY());
						
						this.items[king.getX()][king.getY()] = new NullPiece(king.getX(),king.getX(), this);
						this.items[casX][casY] = king;
						king.changePosition(casX, casY);
						return;
	
					}
				}
			}
			if (this.items[x2][y2].getType() != "  Empty  " && this.items[x2][y2].getSide() == this.items[x1][y1].getSide())
			{
				this.outputString = this.currentPlayerName + ": You cannot make that move this piece is not empty and it's not yor enemy's piece!!";
				this.changePlayer=false;

			} else if (this.items[x1][y1].isEnemy(x2, y2)&& this.items[x2][y2].getSide() != "None") {
				this.outputString = this.currentPlayerName + ": Your " + this.items[x1][y1].getClass().getSimpleName() + " killed " + this.oldPlayerName + "'s " + this.items[x2][y2].getClass().getSimpleName();
				Piece temp = this.items[x1][y1];
				this.items[x1][y1] = new NullPiece(x1,y1, this);
				this.items[x2][y2] = temp;
				this.items[x2][y2].changePosition(x2, y2);
				if(this.isInDanger(wking.getX(), wking.getY(), wking.getSide()) ||(this.isInDanger(bking.getX(), bking.getY(), bking.getSide())))
				{
					this.kingInDanger=true;
				}else
				{
					this.kingInDanger=false;
				}
				if(this.getPiece(x2, y2) instanceof Pawn)
				{
					Pawn p = (Pawn)this.getPiece(x2, y2);
					p.setFirstfalse();
				}
				if((this.items[x2][y2] instanceof King))
				{
					King pieceKing = (King)this.items[x2][y2];
					pieceKing.setFirstMove(false);
				}else if(this.items[x2][y2] instanceof Rook)
				{
					Rook pieceRook = (Rook)this.items[x2][y2];
					pieceRook.setFirstMove(false);
				}
				
			} else 
			{
				Piece temp = this.items[x1][y1];
				this.items[x1][y1] = new NullPiece(x1, y1, this);
				this.items[x2][y2] = temp;
				this.items[x2][y2].changePosition(x2, y2);
				this.getKing();
				if(this.isInDanger(wking.getX(), wking.getY(), wking.getSide()) ||(this.isInDanger(bking.getX(), bking.getY(), bking.getSide())))
				{
					this.kingInDanger=true;
				}else
				{
					this.kingInDanger=false;
				}
				if(this.getPiece(x2, y2) instanceof Pawn)
				{
					Pawn p = (Pawn)this.getPiece(x2, y2);
					p.setFirstfalse();
				}
				if((this.items[x2][y2] instanceof King))
				{
					King pieceKing = (King)this.items[x2][y2];
					pieceKing.setFirstMove(false);
				}else if(this.items[x2][y2] instanceof Rook)
				{
					Rook pieceRook = (Rook)this.items[x2][y2];
					pieceRook.setFirstMove(false);
				}
			}
		}
		isPawnPromoted(x2, y2);
	}


	/**
	 * Returns true if a pawn exists at the point given and is promoted
	 * 
	 * @param p Point at which the promoted pawn is found
	 */
	public void isPawnPromoted(int x, int y){
		Piece tempPiece = this.getPiece(x, y);
		if((tempPiece instanceof Pawn) && (tempPiece.getX()==0 || tempPiece.getX()==7)){
			this.pawnPromoted = true;
		}
	}
	
	/**
	 * Getter for pawnPromoted
	 * @return Boolean set to true if there is a promoted pawn in the board
	 */
	public boolean getPromotion(){
		return pawnPromoted;
	}
	
	/**
	 * Resets the value of pawnPromoted to false
	 */
	public void clearPromotion(){
		this.pawnPromoted = false;
	}
	
	
	/**
	 * A special swap function used in the knight's tour game. It replaces the piece in the original position (point1) by a null piece and the new position
     * (point2) by a contents of point1
	 * 
	 * @param p1 Origin of the move
     * @param p2 Destination of the move
	 */
	public void knightSwap(int x1, int y1, int x2, int y2)
	{
		if(this.items[x1][y1].movePossible(x2, y2)==true)
		{
			if (this.items[x2][y2].getType() != "  Empty  " && this.items[x2][y2].getSide() == this.items[x1][y1].getSide())
			{
				this.outputString = this.currentPlayerName + " you can't make that move. One of your piece's is at the destination";
				changePlayer = false;
			} else if (this.items[x1][y1].isEnemy(x2, y2)&& this.items[x2][y2].getSide() != "None") {
				this.outputString = "Your " + this.items[x1][y1].getType() + " kill the enemy's " + this.items[x2][y2].getType();
				Piece temp = this.items[x1][y1];
				this.items[x1][y1] = new NullPiece(x1, y1, this);
				this.items[x2][y2] = temp;
				this.items[x2][y2].changePosition(x2, y2);
				
			} else 
			{
				Piece temp = this.items[x1][y1];
				this.items[x1][y1] = new NullPiece(x1, y1, this);
				this.items[x2][y2] = temp;
				this.items[x2][y2].changePosition(x2, y2);
			}
		}
	}
	
	/**
	 * Returns an arrayList of points between the given piece and the opponents king. It is used during a
	 * checkmate situation to check if any piece can be moved to block the check.
	 * 
	 * @param p The piece to be checked
	 * @return An arrayList of points between the given piece and the opponents piece
	 */
	public ArrayList<Point> pathWay(Piece p)
	{
		this.getKing();
		ArrayList<Point> points = new ArrayList<Point>();
		Piece king = new NullPiece(0,0,this);
		if(p.getSide().equals("White"))
		{
			king = this.bking;
		}else
		{
			king = this.wking;
		}
		int desx = p.getX();
		int desy = p.getY();
		int inx = king.getX();
		int iny = king.getY();
		if (Math.abs(inx - desx) > 0 && Math.abs(iny - desy) == 0) 	//Horizontal Movement
		{
			if (inx > desx) {										//Moving to the left
				for (int i = desx; i <= inx; i++) {
					if (i != inx)
					{
						points.add(new Point(i, iny));
					}
				}
			} else if (desx > inx) {								//Moving to the right
				for (int i = inx; i <= desx; i++) {
					if (i != desx)
					{
						points.add(new Point(i, desy));
					}
				}
			}
		} 
		else if (Math.abs(inx - desx) == 0 && Math.abs(iny - desy) > 0) {	//Vertical Movement
			if (iny > desy) {												//Moving downwards
				for (int i = desy; i <= iny; i++) {
					if (i != desy)
					{
						points.add(new Point(inx, i));
					}
				}
			} else if (desy > iny) {									//Moving upwards
				for (int i = iny; i <= desy; i++) {
					if (i != desy)
					{
						points.add(new Point(inx, i));
					}
				}
			}
		} else if (Math.abs(inx - desx) == Math.abs(iny - desy)) 
        {
            if (inx < desx && iny < desy) 
            {
                int x = inx;
                int y = iny;
                for (int i = x; i < desx; i++) {
                    x++;
                    y++;
                    Piece temp = this.getPiece(x, y);
                    points.add(new Point(temp.getX(), temp.getY()));
                }
            } else if (inx > desx && iny < desy) 
            {
                int x = inx;
                int y = iny;
                for (int i = y; i < desy; i++) 
                {
                    y++;
                    x--;
                    Piece temp = this.getPiece(x, y);
                    points.add(new Point(temp.getX(), temp.getY()));
                }
            } else if (inx > desx && iny > desy) 
            {
                int x = inx;
                int y = iny;
                for (int i = desy; i < y; i++) 
                {
                    y--;
                    x--;
                    Piece temp = this.getPiece(x, y);
                    points.add(new Point(temp.getX(), temp.getY()));
                }
            } else if (inx < desx && iny > desy) 
            {
                int x = inx;
                int y = iny;
                for (int i = x; i < desx; i++) 
                {
                    y--;
                    x++;
                    Piece temp = this.getPiece(x, y);
                    points.add(new Point(temp.getX(), temp.getY()));
                }
            }
        }
		return points;
	}
	

	/**
	 * Clears the boolean that states if 1 of the kings is in danger. 
	 */
	public void setkingInDanger()
	{
		this.kingInDanger = false;
	}
	
	
	
	
	
	
	/**
	 * Returns true if 1 of the kings on the board is in danger by a piece from the opposite side
	 * 
	 * @return A boolean that states if 1 of the kings is in danger
	 */
	public boolean getkingInDanger()
	{
		return kingInDanger;
	}
	
	
	
	
	
	/**
	 * Sets wking and bking to the corresponding kings on the board.
	 * This is used to keep track of the kings. 
	 */
	public void getKing()
	{
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				if(this.items[i][j] instanceof King)
				{
					if(this.items[i][j].getSide().equals("White"))
					{
						wking = this.items[i][j];
					}else
					{
						bking = this.items[i][j];
					}
				}
			}
		}
	}





	/**
	 * Sets the boolean checkmate to true to state that a checkmate has occurred on the board
	 */
	public void setCheckMate()
	{
		this.checkmate = true;
	}





	/**
	 * Returns ture if a check occurred on the board
	 * 
	 * @return Boolean set to true if a check occurred on the board
	 */
	public boolean getCheckMate()
	{
		return this.checkmate;
	}






	/**
	 * Returns a reference to the 2D array of pieces
	 * 
	 * @return The 2D array of pieces
	 */
	public Piece[][] getItems(){
		return items;
	}

	public void setItems(Piece[][] givenItems)
	{
		this.items = givenItems;
	}

	/**
     * Adds a piece at the location stored in the instance variable 'point' in the piece
     * 
     * @param p Piece to be entered into the board
     */
	public void add(Piece p)
	{
		this.items[p.getX()][p.getY()] = p;
	}




	/**
	 * Returns true if a piece of side given is in danger if placed at the point given by a piece
	 * from the opposite side
	 * 
	 * @return Boolean set to true if a piece is indangered by an enemy's piece at the point given
	 */
	public boolean isInDanger(int x, int y, String side2)
	{
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				if(!this.items[i][j].getSide().equals(side2))	//If it the piece at [i][j] is not a piece from the same side\
				{
					if(this.items[i][j].movePossible(x, y))		//check if the move is possible. I.e., is it indangering a piece at the point given
					{
						if(this.items[i][j] instanceof Pawn)
						{
							if(Math.abs(this.items[i][j].getX()-x)>=1 && Math.abs(this.items[i][j].getY()-y)==0)
							{
								continue;
							}
						}
						return true;
					}
				}
			}
		}
		return false;
	}



	/**
	 * Checks which king is in danger. If the white king is in danger, it 
	 * returns true. Else, it returns false
	 * 
	 * @return Boolean that is set to true if the white king is the king in danger
	 */
	public boolean whiteKingInDanger()
    {
        for(int i=0; i<SIZE; i++)
        {
            for(int j=0; j<SIZE; j++)
            {
                if(this.items[i][j].getType().equals("   King  "))
                {
                    if(this.isInDanger(i, j, this.items[i][j].getSide()))
                    {
                        return true;
                    }else
                    {
                        return false;
                    }
                }
            }
        }
        return false;
    }

	
	
	
	
	
	
	
	
	
	
	
	public Board createBoard()
	{
		Board b = new Board();
		for(int i=0; i<SIZE; i++)
		{
			for(int j=0; j<SIZE; j++)
			{
				if(this.items[i][j] instanceof NullPiece)
				{
					NullPiece p = new NullPiece(i, j, b);
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof Pawn)
				{
					Pawn k = (Pawn)this.items[i][j];
					Pawn p = new Pawn(i, j, b, k.getSide());
					p.firstMove = k.firstMove;
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof Knight)
				{
					Knight k = (Knight)this.items[i][j];
					Knight p = new Knight(i, j, b, k.getSide());
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof Rook)
				{
					Rook k = (Rook)this.items[i][j];
					Rook p = new Rook(i, j, b, k.getSide());
					p.firstMove = k.firstMove;
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof Queen)
				{
					Queen k = (Queen)this.items[i][j];
					Queen p = new Queen(i, j, b, k.getSide());
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof Bishop)
				{
					Bishop k = (Bishop)this.items[i][j];
					Bishop p = new Bishop(i, j, b, k.getSide());
					b.items[i][j] = p;
				}else if(this.items[i][j] instanceof King)
				{
					King k = (King)this.items[i][j];
					King p = new King(i, j, b, k.getSide());
					p.firstMove = k.firstMove;
					p.castlingPossible = k.castlingPossible;
					b.items[i][j] = p;
				}
			}
		}
		//King blackking = new King(this.bking.getX(), this.bking.getY(), b, this.bking.getSide());
		//b.bking = blackking;
		boolean cp = this.changePlayer;
		b.changePlayer = cp;
		boolean cm = this.checkmate;
		b.checkmate = cm;
		String cpn = new String(this.currentPlayerName);
		b.currentPlayerName = cpn;
		boolean kid = this.kingInDanger;
		b.kingInDanger = kid;
		String opn = new String(this.oldPlayerName);
		b.oldPlayerName = opn;
		String ops = new String(this.outputString);
		b.outputString = ops;
		boolean pp = this.pawnPromoted;
		b.pawnPromoted = pp;
		//King whiteking = new King(this.wking.getX(), this.wking.getY(), b, this.wking.getSide());
		//b.wking = whiteking;
		return b;
		
	}
	
	
	
	
	
	
	
	
	
	
	/**
     * Outputs a string representation of the current state of the board including the pieces' names
     */
	public void print() {
        String string = new String();
        string += "#####################################################################################";
        string += "\n";
        string += "  |    0    |    1    |    2    |    3    |    4    |    5    |    6    |    7    |";
        string += "\n";
        string += "-------------------------------------------------------------------------------------";
        string += "\n";
        for (int i = SIZE-1; i >= 0; i--) {
            string += i + " |";
            for (int j = 0; j < SIZE; j++) {
                string += this.items[i][j].getType() + "|";
            }
            string += " " + i;
            string += "\n";
            string += "-------------------------------------------------------------------------------------";
            string += "\n";
        }
        string += "  |    0    |    1    |    2    |    3    |    4    |    5    |    6    |    7    |";
        string += "\n";
        string += "#####################################################################################";
        string += "\n";
        System.out.println(string);
    }
   
	/**
     * Outputs a string representation of the current state of the board including the pieces' names
     * rotated so the black pieces are located at the bottom of the board
     */
    public void printBlack() {
        String string = new String();
        string += "#####################################################################################";
        string += "\n";
        string += "  |    0    |    1    |    2    |    3    |    4    |    5    |    6    |    7    |";
        string += "\n";
        string += "-------------------------------------------------------------------------------------";
        string += "\n";
        for (int i = 0; i <= SIZE-1; i++) {
            string += i + " |";
            for (int j = 0; j < SIZE; j++) {
                string += this.items[i][j].getType() + "|";
            }
            string += " " + i;
            string += "\n";
            string += "-------------------------------------------------------------------------------------";
            string += "\n";
        }
        string += "  |    0    |    1    |    2    |    3    |    4    |    5    |    6    |    7    |";
        string += "\n";
        string += "#####################################################################################";
        string += "\n";
        System.out.println(string);
    }

}